home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / WINDOWS / RX11.ARJ / RX.C < prev    next >
Text File  |  1992-08-01  |  48KB  |  1,538 lines

  1. /*--------------------------------------------------------------------      */
  2. /* rxvar.h                                                                  */
  3. /*NOTE:                                                                     */
  4. /*This is a completly experimental program in it's pre-beta version.        */
  5. /*It is not guaranteed to work properly under all circumstances, although   */
  6. /*it has been tested for a couple of weeks. Everyone who uses this program  */
  7. /*does this on his own risk, so if your machine explodes, don't tell me     */
  8. /*you didn't know.                                                          */
  9. /*                                                                          */
  10. /*Andreas Gruen releases this software "as is", with no express or          */
  11. /*implied warranty, including, but not limited to, the implied warranties   */
  12. /*of merchantability and fitness for a particular purpose.                  */
  13. /*                                                                          */
  14. /*This program is completly free for everyone.                              */
  15. /*You can do with it and its sources whatever you want, but it would        */
  16. /*be fine to leave my name somewhere in the program or startup-banner.      */
  17. /*---------------------------------------------------------------------     */
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include "rx.h"
  21. #include "rxvar.h"
  22.  
  23. char copyleft[] = " (c) Copyright Andreas Gruen 1991,1992.  All rights reserved.";
  24.  
  25. #define EXIT(X) {fprintf(stderr,"RX: %s\n",X);exit(1);}
  26.  
  27. #define ALIGN(X,Y) ( (ULONG)(X) << (Y) )    /* align to 2^Y   */
  28.  
  29. #define TMPSIZE 16384
  30.  
  31. #define MAX(X,Y) (((X) > (Y)) ? (X) : (Y))   /* for those who don't have it*/
  32. #define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
  33.  
  34. #define GOT_TEXT 0
  35. #define GOT_ID   1
  36.  
  37. #define MEMF_DISC  0x1000         /* memory-options*/
  38. #define MEMF_MOVE  0x0010
  39. #define MEMF_PREL  0x0040
  40. #define FLAG_MASK  0x1050
  41.  
  42. DOSHEAD doshead;             /* DOS EXE-header*/
  43. OSHEAD oshead;               /* WIN/ OS2-header*/
  44. UCHAR tmpbuf[TMPSIZE];
  45. int filenum;
  46. char verbose = 0;
  47. char *resname[16] = { "---","CURSOR","BITMAP","ICON","MENU","DIALOG",
  48.                       "STRING","FONTDIR","FONT","ACCELERATOR","RCDATA",
  49.                       "(unknown)-11-","CURSORHEADER","(unknown)-13-",
  50.                       "ICONHEADER","NAMETABLE" };
  51.  
  52. char *stdclassname[6] = { "button","edit","static",
  53.                         "listbox","scrollbar","combobox" };
  54.  
  55. char spaces[] =
  56.   "                                                                ";
  57.  
  58. USHORT ntentry = 0;
  59. #define MAXSPACE 64
  60. #define SPC(X) (spaces + (MAXSPACE-(X)))
  61. #define INDENTVAL 2
  62. #define IS_MENUOPT (MF_GRAYED|MF_DISABLED|MF_CHECKED|MF_MENUBARBREAK|MF_MENUBREAK)
  63.  
  64. int get_rctab(FILE*);
  65. int get_lstrings(FILE*);
  66. int get_rcentry(FILE *,USHORT);
  67.  
  68. int put_icon(FILE *,FILE *,long);
  69. int put_font(FILE *,FILE *,long);
  70. int put_bitmap(FILE *,FILE *,long);
  71. int put_cursor(FILE *,FILE *,long);
  72. int put_menu(FILE *,FILE *,long,char *,USHORT,USHORT);
  73. int put_dialog(FILE *,FILE *,long,char *,USHORT,USHORT);
  74. int put_nametab(FILE *,FILE *,long);
  75. int put_strings(FILE *,FILE *,long,char *,USHORT,USHORT);
  76. int put_rcdata(FILE *,FILE *,long,long,char *,USHORT,USHORT);
  77. int put_accel(FILE *,FILE *,long,char *,USHORT,USHORT);
  78.  
  79. int print_styles(FILE *,ULONG,UCHAR);
  80. char *lookup_name(RCENTRY *, USHORT);
  81. char * get_virttext(UCHAR);
  82. int read_string(FILE *,char *);
  83. int read_nstring(FILE *,char *,USHORT);
  84. USHORT read_word(FILE *);
  85. ULONG read_dword(FILE *);
  86. UCHAR read_byte(FILE *);
  87. int copy_block(FILE * ,FILE *, ULONG);
  88. int read_textorid(FILE *,char*,int *);
  89.  
  90. int iflg,mflg,cflg,bflg,dflg,sflg,fflg,aflg,nflg,rflg;
  91. int i_num,m_num,c_num,b_num,d_num,s_num,f_num,a_num,n_num,r_num,xtract;
  92.  
  93. char base_file[128],rc_file[128], temp_name[128];
  94. char exe_file[128];
  95. FILE *fprc;                /* .RC-File  */
  96. main(argc,argv)
  97.   int argc;
  98.   char *argv[];
  99.   {
  100.     int i,n;
  101.     FILE *fp;
  102.     USHORT dossign,ossign;
  103.     ULONG newhead;
  104.     char *s;
  105.  
  106.     dossign = *( (USHORT *)"MZ");       /* well, hum, but it works*/
  107.     ossign = *( (USHORT *)"NE");
  108.  
  109.     nflg = iflg = mflg = cflg = bflg = dflg = 0;
  110.     sflg = fflg = aflg = rflg = 0;
  111.     n_num = i_num = m_num = c_num = b_num = d_num = 0;
  112.     s_num = f_num = a_num = r_num = 0;
  113.     xtract = 0;
  114.  
  115.     while(--argc > 0 && (*++argv)[0] == '-')
  116.       {
  117.         for(s = (*argv)+1; *s && argc > 0 ; s++)
  118.           {
  119.             switch(*s)
  120.               {
  121.                 case 'i':
  122.                  iflg = xtract = 1;
  123.                  break;
  124.                 case 'm':
  125.                  mflg = xtract = 1;
  126.                  break;
  127.                 case 'c':
  128.                  cflg = xtract = 1;
  129.                  break;
  130.                 case 'b':
  131.                  bflg = xtract = 1;
  132.                  break;
  133.                 case 'd':
  134.                  dflg = xtract = 1;
  135.                  break;
  136.                 case 's':
  137.                  sflg = xtract = 1;
  138.                  break;
  139.                 case 'f':
  140.                  fflg = xtract = 1;
  141.                  break;
  142.                 case 'a':
  143.                  aflg = xtract = 1;
  144.                  break;
  145.                 case 'n':
  146.                  nflg = 1;
  147.                  break;
  148.                 case 'r':
  149.                  rflg = xtract = 1;
  150.                  break;
  151.                 case 'x':
  152.                  nflg = iflg = mflg = cflg = bflg = dflg = 1;
  153.                  sflg = fflg = aflg = rflg = xtract = 1;
  154.                  break;
  155.                 case 'v':
  156.                   verbose = 1;
  157.                   break;
  158.                 case '?':
  159.                 case 'h':
  160.                   argc = -1;
  161.                   break;
  162.                 default:
  163.                   fprintf(stderr,"illegal option '%c'\n",*s);
  164.                   argc = -1;
  165.                   break;
  166.               }
  167.          }
  168.       }
  169.     if(argc <= 0)
  170.       {
  171.         fprintf(stderr,"RX V1.1: %s\n",copyleft);
  172.         fprintf(stderr,"Usage: RX -{ibcmdsfav} filename [outputname]\n");
  173.         fprintf(stderr,"             -i   : extract ICONs\n");
  174.         fprintf(stderr,"             -b   : extract BITMAPs\n");
  175.         fprintf(stderr,"             -c   : extract CURSORs\n");
  176.         fprintf(stderr,"             -m   : extract MENUs\n");
  177.         fprintf(stderr,"             -d   : extract DIALOGs\n");
  178.         fprintf(stderr,"             -s   : extract STRINGTABLEs\n");
  179.         fprintf(stderr,"             -f   : extract FONTs\n");
  180.         fprintf(stderr,"             -a   : extract ACCELERATORS\n");
  181.         fprintf(stderr,"             -n   : extract NAMETABLE (internal use)\n");
  182.         fprintf(stderr,"             -r   : extract RCDATA\n");
  183.         fprintf(stderr,"             -x   : extract all\n");
  184.         fprintf(stderr,"             -v   : verbose mode\n");
  185.         fprintf(stderr,"separate files will be created and\n");
  186.         fprintf(stderr,"#include'd in RC-File\n");
  187.         exit(1);
  188.       }
  189.  
  190.     strcpy(exe_file,argv[0]);
  191.     strupr(exe_file);
  192.     if( (fp = fopen(exe_file,"rb")) == NULL)
  193.       {
  194.         strcat(exe_file,".EXE");
  195.         if( (fp = fopen(exe_file,"rb")) == NULL)
  196.           EXIT("can't open infile");
  197.       }
  198.     printf("RX V1.1: %s\n",copyleft);
  199.     printf("Processing  '%s'\n",exe_file);
  200.     if(argc > 1)
  201.       {
  202.         strcpy(base_file,argv[1]);
  203.       }
  204.     else
  205.       {
  206.         strcpy(base_file,exe_file);
  207.       }
  208.     /* look if there's an ext. (like .EXE),
  209.        ext. are 4 chars max including '.'
  210.        if yes : strip it */
  211.  
  212.     s = base_file + strlen(base_file) - 4;
  213.     while(*s)
  214.       {
  215.         if(*s == '.')
  216.           {
  217.             *s = '\0';   /* strip*/
  218.             break;       /* and go */
  219.           }
  220.         s++;
  221.       }
  222.  
  223.     if(xtract)
  224.       {
  225.         strcpy(temp_name,base_file);
  226.         strcat(temp_name,".rc");
  227.       }
  228.     else
  229.       {
  230.         strcpy(temp_name,"NUL");       /* no output,
  231.                                           could be coded better, I know
  232.                                           (sigh) */
  233.       }
  234.     if( (fprc = fopen(temp_name,"w")) == NULL)  EXIT("can't open RC-file");
  235.  
  236.     fprintf(fprc,"#include <windows.h>\n\n");   /* must be*/
  237.  
  238.     fread(&doshead,sizeof(DOSHEAD),1,fp);
  239.  
  240.     if(doshead.sign != dossign)    EXIT("Invalid file (no EXE, DLL...)");
  241.  
  242.     if(verbose)
  243.       printf("Header-Size : %ld \n",(ULONG)(doshead.nparhead) << 4);
  244.  
  245.     if(doshead.posreloc != 0x40)
  246.       {
  247.         fclose(fp);
  248.         EXIT("No Windows/OS2-executable or lib");       /*DOS-Exe*/
  249.       }
  250.  
  251.     newhead = doshead.posnewhead;
  252.     if(verbose)
  253.       printf("OS-Header at : %lX \n",newhead);
  254.  
  255.     fseek(fp,newhead,0);
  256.     fread(&oshead,sizeof(OSHEAD),1,fp);
  257.  
  258.     if(oshead.sign != ossign)
  259.       EXIT("Invalid file (no EXE, DLL...) [new header]");
  260.  
  261.     build_nametable(fp);
  262.  
  263.     get_rctab(fp);     /* view/extract resources*/
  264.  
  265.     fclose(fp);
  266.     fclose(fprc);
  267.     return(0);
  268.   }
  269. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  270.  
  271. get_rctab(fp)
  272.   FILE *fp;
  273.   {
  274.     USHORT rcalign;
  275.     ULONG rctab;
  276.  
  277.     rctab = (ULONG)oshead.posrctab+doshead.posnewhead;
  278.     if(verbose)
  279.       printf("Resourcetable at offset: %04lX\n",rctab);
  280.  
  281.     fseek(fp,rctab,0);
  282.     rcalign = read_word(fp);        /* padding size = 2^rcalign bytes*/
  283.  
  284.     if(verbose)
  285.       printf("Resource-alignment = %d bytes\n",1<<rcalign);
  286.     while(get_rcentry(fp,rcalign));
  287.     get_lstrings(fp);
  288.     return(0);
  289.   }
  290. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  291.  
  292. build_nametable(fp)
  293.   FILE *fp;
  294.   {
  295.     USHORT rcalign;
  296.     ULONG rctab;
  297.     RCENTRY rce;
  298.     USHORT rctyp,nrc,i;
  299.     long tpos,tlen;
  300.  
  301.     rctab = (ULONG)oshead.posrctab+doshead.posnewhead;
  302.  
  303.     fseek(fp,rctab,0);
  304.     rcalign = read_word(fp);        /* padding size = 2^rcalign bytes*/
  305.  
  306.     rctyp = read_word(fp);
  307.     ntentry = 0;
  308.     while(rctyp)
  309.       {
  310.         nrc = read_word(fp);
  311.         read_dword(fp);               /*skip reserved bytes*/
  312.         if((rctyp & 0x7fff) == 0x000f)   /* joop, we have it*/
  313.           {
  314.             for(i = 0; i < nrc; i++)
  315.               {
  316.                 fread(&rce,sizeof(RCENTRY),1,fp);
  317.                 tpos = ALIGN(rce.datp,rcalign);
  318.                 tlen = ALIGN(rce.len,rcalign);
  319.                 fill_ntable(fp,tpos);
  320.               }
  321.             break;
  322.           }
  323.         else
  324.           {
  325.             fseek(fp,(ULONG)sizeof(RCENTRY)*(ULONG)nrc,1);  /*skip it*/
  326.           }
  327.         rctyp = read_word(fp);
  328.       }
  329.     return(ntentry);
  330.   }
  331. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  332.  
  333. int fill_ntable(fp,filep)
  334.   FILE *fp;
  335.   long filep;
  336.   {
  337.     long fpos;
  338.     char xname[16];
  339.     char rcname[256];
  340.     USHORT len,rctype,rcnum,i;
  341.     long filelen;
  342.  
  343.     fpos = ftell(fp);
  344.  
  345.     fseek(fp,filep,0);
  346.  
  347.     while(len = read_word(fp))
  348.       {
  349.         rctype = read_word(fp);
  350.         rctype &= 0x000f;
  351.         rctype %= 11;             /* refs to icons are refs to iconheaders
  352.                                      same for bitmaps, think about that */
  353.         nametab[ntentry].type = rctype;
  354.         nametab[ntentry].num = read_word(fp) & 0x7fff;
  355.         read_byte(fp);            /* skip 1 byte */
  356.         fread(nametab[ntentry].name,1,len-7,fp);
  357.                  /* may use read_string, but this is safe*/
  358.         ntentry++;
  359.       }
  360.     fseek(fp,fpos,0);
  361.     return(0);
  362.   }
  363. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  364.  
  365. get_lstrings(fp)
  366.   FILE *fp;
  367.   {
  368.     UCHAR clen;
  369.     USHORT len;
  370.     char buff[256];
  371.  
  372.     while(clen = read_byte(fp))
  373.       {
  374.         read_nstring(fp,buff,(USHORT)clen);
  375.         printf("Resource-Name : %s\n",buff);
  376.       }
  377.     return(0);
  378.   }
  379.  
  380. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  381.  
  382. get_rcentry(fp,rcalign)
  383.   FILE *fp;
  384.   USHORT rcalign;
  385.   {
  386.  
  387.     RCENTRY rce;
  388.     FILE *fpout;
  389.     USHORT rctyp,nrc,i;
  390.     char *pname;
  391.     long tpos,tlen;
  392.  
  393.     fread(&rctyp,2,1,fp);
  394.     if(rctyp == 0)   return(0);    /* got all */
  395.  
  396.     fread(&nrc,2,1,fp);
  397.     fread(tmpbuf,1,4,fp);          /*reserved bytes*/
  398.  
  399.  
  400.     if((rctyp & 0x7fff) < 16)
  401.       {
  402.         printf("%u %s (s)\n",nrc,resname[rctyp & 0xf]);
  403.       }
  404.     else
  405.       {
  406.         printf("unknown resource-type %04X (%u resources)\n",nrc,rctyp);
  407.       }
  408.  
  409.     for(i = 0; i < nrc; i++)
  410.       {
  411.         fread(&rce,sizeof(RCENTRY),1,fp);
  412.         tpos = ALIGN(rce.datp,rcalign);
  413.         tlen = ALIGN(rce.len,rcalign);
  414.         if(verbose)
  415.           printf("offset %04lX  len = %lu ord= %04X flags=%04X\n"
  416.                  ,tpos,tlen,rce.id,rce.flags);
  417.  
  418. /* extract it */
  419.         switch(rctyp & 0x0fff)
  420.           {
  421.             case 0x0001:               /*CURSOR-resource*/
  422.               if(cflg)
  423.                 {
  424.                   sprintf(temp_name,"CURS%d.CUR",c_num++);
  425.                   if((fpout = fopen(temp_name,"wb")) == NULL)  EXIT("file-write failed");
  426.                   put_cursor(fp,fpout,tpos);
  427.                   fclose(fpout);
  428.                   rce.id--;         /* don't ask me why
  429.                                        but cursor-numbers start with 2*/
  430.                   if(pname = lookup_name(&rce,rctyp))
  431.                     fprintf(fprc,"%s CURSOR ",pname);
  432.                   else
  433.                     fprintf(fprc,"%d CURSOR ",rce.id & 0x7fff);
  434.                   print_flags(fprc,rce.flags,rctyp & 0x0f);
  435.                   fprintf(fprc,"%s\n",temp_name);
  436.                 }
  437.               break;
  438.             case 0x0002:               /*BITMAP-resource*/
  439.               if(bflg)
  440.                 {
  441.                   sprintf(temp_name,"BITM%d.BMP",b_num++);
  442.                   if((fpout = fopen(temp_name,"wb")) == NULL)  EXIT("file-write failed");
  443.                   put_bitmap(fp,fpout,tpos);
  444.                   fclose(fpout);
  445.                   if(pname = lookup_name(&rce,rctyp))
  446.                     fprintf(fprc,"%s BITMAP ",pname);
  447.                   else
  448.                     fprintf(fprc,"%d BITMAP ",rce.id & 0x7fff);
  449.                   print_flags(fprc,rce.flags,rctyp & 0x0f);
  450.                   fprintf(fprc,"%s\n",temp_name);
  451.                 }
  452.               break;
  453.             case 0x0003:               /*ICON-resource*/
  454.               if(iflg)
  455.                 {
  456.                   sprintf(temp_name,"ICON%d.ICO",i_num++);
  457.                   if((fpout = fopen(temp_name,"wb")) == NULL)  EXIT("file-write failed");
  458.                   put_icon(fp,fpout,tpos);
  459.                   fclose(fpout);
  460.                   if(pname = lookup_name(&rce,rctyp))
  461.                     fprintf(fprc,"%s ICON ",pname);
  462.                   else
  463.                     fprintf(fprc,"%d ICON ",rce.id & 0x7fff);
  464.                   print_flags(fprc,rce.flags,rctyp & 0x0f);
  465.                   fprintf(fprc,"%s\n",temp_name);
  466.                 }
  467.               break;
  468.             case 0x0008:               /*FONT-resource  */
  469.               if(fflg)
  470.                 {
  471.                   sprintf(temp_name,"FONT%d.FNT",f_num++);
  472.                   if((fpout = fopen(temp_name,"wb")) == NULL)  EXIT("file-write failed");
  473.                   put_font(fp,fpout,tpos);
  474.                   fclose(fpout);
  475.                   /* fonts don't have names*/
  476.                   fprintf(fprc,"%d FONT ",rce.id & 0x7fff);
  477.                   print_flags(fprc,rce.flags,rctyp & 0x0f);
  478.                   fprintf(fprc,"%s\n",temp_name);
  479.                 }
  480.               break;
  481.             case 0x0004:               /*MENU-resource */
  482.               if(mflg)
  483.                 {
  484.                   strcpy(temp_name,base_file);
  485.                   strcat(temp_name,".MEN");
  486.                   if(mflg++ == 1)    /* first menu should overwrite*/
  487.                     {
  488.                       fprintf(fprc,"#include \"%s\"\n",temp_name);
  489.                       if((fpout = fopen(temp_name,"w")) == NULL)
  490.                         EXIT("file-write failed");
  491.                     }
  492.                   else
  493.                     {
  494.                       if((fpout = fopen(temp_name,"a")) == NULL)
  495.                         EXIT("file-write failed");
  496.                     }
  497.                   pname = lookup_name(&rce,rctyp);
  498.                   put_menu(fp,fpout,tpos,pname,rce.id & 0x7fff,rce.flags);
  499.                   fclose(fpout);
  500.                 }
  501.               break;
  502.             case 0x0005:               /*DIALOG-resource */
  503.               if(dflg)
  504.                 {
  505.                   strcpy(temp_name,base_file);
  506.                   strcat(temp_name,".DLG");
  507.                   if(dflg++ == 1)    /* first should overwrite*/
  508.                     {
  509.                       fprintf(fprc,"#include \"%s\"\n",temp_name);
  510.                       if((fpout = fopen(temp_name,"w")) == NULL)
  511.                         EXIT("file-write failed");
  512.                     }
  513.                   else
  514.                     {
  515.                       if((fpout = fopen(temp_name,"a")) == NULL)
  516.                         EXIT("file-write failed");
  517.                     }
  518.                   pname = lookup_name(&rce,rctyp);
  519.                   put_dialog(fp,fpout,tpos,pname,rce.id & 0x7fff,rce.flags);
  520.                   fclose(fpout);
  521.                 }
  522.               break;
  523.             case 0x0006:               /*STRING-resource*/
  524.               if(sflg)
  525.                 {
  526.                   strcpy(temp_name,base_file);
  527.                   strcat(temp_name,".STR");
  528.                   if(sflg++ == 1)    /* first should overwrite*/
  529.                     {
  530.                       fprintf(fprc,"#include \"%s\"\n",temp_name);
  531.                       if((fpout = fopen(temp_name,"w")) == NULL)
  532.                         EXIT("file-write failed");
  533.                     }
  534.                   else
  535.                     {
  536.                       if((fpout = fopen(temp_name,"a")) == NULL)
  537.                         EXIT("file-write failed");
  538.                     }
  539.                   pname = lookup_name(&rce,rctyp);
  540.                   put_strings(fp,fpout,tpos,pname,rce.id & 0x7fff,rce.flags);
  541.                   fclose(fpout);
  542.                 }
  543.               break;
  544.             case 0x0007:               /*FONTDIR-resource,
  545.                                          not implemented*/
  546.               break;
  547.             case 0x0009:               /*ACCEL-resource*/
  548.               if(aflg)
  549.                 {
  550.                   strcpy(temp_name,base_file);
  551.                   strcat(temp_name,".ACC");
  552.                   if(aflg++ == 1)    /* first should overwrite*/
  553.                     {
  554.                       fprintf(fprc,"#include \"%s\"\n",temp_name);
  555.                       if((fpout = fopen(temp_name,"w")) == NULL)
  556.                         EXIT("file-write failed");
  557.                     }
  558.                   else
  559.                     {
  560.                       if((fpout = fopen(temp_name,"a")) == NULL)
  561.                         EXIT("file-write failed");
  562.                     }
  563.                   pname = lookup_name(&rce,rctyp);
  564.                   put_accel(fp,fpout,tpos,pname,rce.id & 0x7fff,rce.flags);
  565.                   fclose(fpout);
  566.                 }
  567.               break;
  568.             case 0x000a:               /*RCDATA-resource */
  569.               if(rflg)
  570.                 {
  571.                   strcpy(temp_name,base_file);
  572.                   strcat(temp_name,".RCD");
  573.                   if(rflg++ == 1)    /* first should overwrite*/
  574.                     {
  575.                       fprintf(fprc,"#include \"%s\"\n",temp_name);
  576.                       if((fpout = fopen(temp_name,"w")) == NULL)
  577.                         EXIT("file-write failed");
  578.                     }
  579.                   else
  580.                     {
  581.                       if((fpout = fopen(temp_name,"a")) == NULL)
  582.                         EXIT("file-write failed");
  583.                     }
  584.                   pname = lookup_name(&rce,rctyp);
  585.                   put_rcdata(fp,fpout,tpos,tlen,pname,rce.id & 0x7fff,rce.flags);
  586.                   fclose(fpout);
  587.                 }
  588.               break;
  589.             case 0x000c:               /*CURSOR-header-resource,
  590.                                          undocumented, not needed*/
  591.               break;
  592.             case 0x000e:               /*ICON-header-resource,
  593.                                          undocumented, no need*/
  594.               break;
  595.             case 0x000f:               /*NAMETABLE-resource,
  596.                                          undocumented (?)*/
  597.               if(nflg)
  598.                 {
  599.                   strcpy(temp_name,base_file);
  600.                   strcat(temp_name,".NAM");
  601.                   if(nflg++ == 1)    /* first should overwrite*/
  602.                     {
  603.                       if((fpout = fopen(temp_name,"w")) == NULL)
  604.                         EXIT("file-write failed");
  605.                     }
  606.                   else
  607.                     {
  608.                       if((fpout = fopen(temp_name,"a")) == NULL)
  609.                         EXIT("file-write failed");
  610.                     }
  611.                   put_nametab(fp,fpout,tpos);
  612.                   fclose(fpout);
  613.                 }
  614.               break;
  615.             default:
  616.               break;
  617.           }
  618.       }
  619.     return(1);
  620.   }
  621. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  622. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  623.  
  624. int put_icon(fp,fpout,filep)
  625.   FILE *fp,*fpout;
  626.   long filep;
  627.   {
  628.     long fpos;
  629.     char xname[16];
  630.     BMHEAD dib;
  631.     ICONHEAD ih;
  632.     USHORT len;
  633.     long filelen;
  634.  
  635.     fpos = ftell(fp);
  636.  
  637.     fseek(fp,filep,0);
  638.     fread(&dib,sizeof(BMHEAD),1,fp);
  639.  
  640.     fseek(fp,filep,0);
  641.  
  642.     ih.reserv1 = 0;
  643.     ih.rctype  = 1;
  644.     ih.count   = 1;                        /*images in file*/
  645.     ih.wid     = (UCHAR)dib.width;
  646.     ih.hei     = (UCHAR)(dib.height>>1);   /*important ! AND-MASK in DIB*/
  647.     ih.colors  = (UCHAR)(1<<dib.bitcount);
  648.     ih.reserv2 = 0;
  649.     ih.xhot    = 0;                        /*reserved for icons*/
  650.     ih.yhot    = 0;
  651.     ih.DIBsize = dib.size +
  652.                  4L*(ULONG)ih.colors +    /* size of colortable*/
  653.                                           /* size of bitmap*/
  654.                  ((ULONG)ih.wid*(ULONG)ih.hei * (ULONG)dib.bitcount)/8 +
  655.                                           /*size of bitmask*/
  656.                  ((ULONG)ih.wid*(ULONG)ih.hei)/8;
  657.     ih.DIBoff  = sizeof(ICONHEAD);         /*hope for packed struct's*/
  658.  
  659.     fwrite(&ih,sizeof(ICONHEAD),1,fpout);
  660.  
  661.     copy_block(fpout,fp,ih.DIBsize);
  662.  
  663.     fseek(fp,fpos,0);
  664.     return(0);
  665.   }
  666. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  667.  
  668. int put_cursor(fp,fpout,filep)
  669.   FILE *fp,*fpout;
  670.   long filep;
  671.   {
  672.     long fpos;
  673.     char xname[16];
  674.     BMHEAD dib;
  675.     CURSORHEAD cu;
  676.     USHORT len;
  677.     long filelen;
  678.  
  679.     fpos = ftell(fp);
  680.  
  681.     fseek(fp,filep,0);
  682.     read_dword(fp);                     /* don't ask me why, skip dummy*/
  683.     fread(&dib,sizeof(BMHEAD),1,fp);
  684.  
  685.     fseek(fp,filep,0);
  686.     read_dword(fp);                     /* don't ask me why, skip dummy*/
  687.  
  688.     cu.reserv1 = 0;
  689.     cu.rctype  = 2;
  690.     cu.count   = 1;                        /*images in file*/
  691.     cu.wid     = (UCHAR)dib.width;
  692.     cu.hei     = (UCHAR)(dib.height>>1);   /*important ! AND-MASK in DIB*/
  693.     cu.colors  = (UCHAR)(1<<dib.bitcount);
  694.     cu.reserv2 = 0;
  695.     cu.xhot    = 0;                        /*hotspot set to 0,0, sorry*/
  696.     cu.yhot    = 0;
  697.     cu.DIBsize = dib.size +
  698.                  4L*(ULONG)cu.colors +    /* size of colortable*/
  699.                                           /* size of bitmap*/
  700.                  ((ULONG)cu.wid*(ULONG)cu.hei * (ULONG)dib.bitcount)/8 +
  701.                                           /*size of bitmask*/
  702.                  ((ULONG)cu.wid*(ULONG)cu.hei)/8;
  703.     cu.DIBoff  = sizeof(CURSORHEAD);         /*hope for packed struct's*/
  704.  
  705.     fwrite(&cu,sizeof(CURSORHEAD),1,fpout);
  706.  
  707.     copy_block(fpout,fp,cu.DIBsize);
  708.  
  709.     fseek(fp,fpos,0);
  710.     return(0);
  711.   }
  712. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  713.  
  714. int put_bitmap(fp,fpout,filep)
  715.   FILE *fp,*fpout;
  716.   long filep;
  717.   {
  718.     long fpos;
  719.     char xname[16];
  720.     BMHEAD dib;
  721.     BMFHEAD bfh;
  722.     USHORT len;
  723.     long filelen;
  724.     ULONG bytesinline;           /* BUG in RX 1.0, bits must be aligned on
  725.                                 32-bit boundaries*/
  726.  
  727.     fpos = ftell(fp);
  728.  
  729.     fseek(fp,filep,0);
  730.     fread(&dib,sizeof(BMHEAD),1,fp);
  731.  
  732.     fseek(fp,filep,0);
  733.  
  734.     bytesinline = ((ULONG)dib.width* (ULONG)dib.bitcount)/8;
  735.     bytesinline = (bytesinline + 3L) & 0xFFFFFFFC;  /* pad to 32-bit */
  736.  
  737.     bfh.sign    = (USHORT)'B' + (USHORT)'M'* 256;
  738.     bfh.fsize   = (ULONG)sizeof(BMFHEAD)+    /*filesize*/
  739.                   dib.size +
  740.                   (ULONG)(1<<dib.bitcount) * 4L +
  741.                   bytesinline * (ULONG)dib.height;
  742.  
  743.                         /*offset to bits in file*/
  744.     bfh.offset  = (ULONG)sizeof(BMFHEAD)+
  745.                   dib.size +
  746.                   (ULONG)(1<<dib.bitcount) * 4L;
  747.  
  748.     bfh.reserv1 = bfh.reserv2 = 0;
  749.  
  750.     fwrite(&bfh,sizeof(BMFHEAD),1,fpout);
  751.  
  752.     copy_block(fpout,fp,bfh.fsize - sizeof(BMFHEAD));
  753.  
  754.     fseek(fp,fpos,0);
  755.     return(0);
  756.   }
  757. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  758.  
  759. int put_font(fp,fpout,filep)
  760.   FILE *fp,*fpout;
  761.   long filep;
  762.   {
  763.     long fpos;
  764.     char xname[16];
  765.     USHORT len;
  766.     long filelen;
  767.  
  768.     fpos = ftell(fp);
  769.  
  770.     fseek(fp,filep,0);
  771.     read_word(fp);                /*skip dummy*/
  772.     filelen = read_dword(fp);
  773.  
  774.     fseek(fp,filep,0);    /* and back*/
  775.  
  776.     copy_block(fpout,fp,filelen);
  777.  
  778.     fseek(fp,fpos,0);
  779.     return(0);
  780.   }
  781. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  782.  
  783. int put_strings(fp,fpout,filep,sname,sid,flags)
  784.   FILE *fp,*fpout;
  785.   long filep;
  786.   char *sname;
  787.   USHORT sid;
  788.   USHORT flags;
  789.                     /* ATTENTION: stringtable names not supported
  790.                        (well, officially not allowed but possible,
  791.                          try it !   Maybe I will work on it) */
  792.   {
  793.     long fpos;
  794.     char xname[16];
  795.     char string[257];   /* enough !*/
  796.     UCHAR slen;
  797.     USHORT len;
  798.     USHORT i,n;
  799.     UCHAR *strp;
  800.     long filelen;
  801.  
  802.     fpos = ftell(fp);
  803.  
  804.     fseek(fp,filep,0);
  805.  
  806.     fprintf(fpout,"STRINGTABLE ");
  807.     print_flags(fpout,flags,6);
  808.     fprintf(fpout,"\nBEGIN\n");
  809.     for(i = 0; i < 16; i++)     /*16 strings in a segment */
  810.       {
  811.         slen = read_byte(fp);
  812.         if(slen)                    /* ugly-but-must-be*/
  813.           {
  814.             read_nstring(fp,string,slen);
  815.             strp = string;
  816.             fprintf(fpout,"  %u,\"",i+(sid-1)*16);
  817.             while(*strp)
  818.               {
  819.                 if(*strp < 0x20)
  820.                   fprintf(fpout,"\\%03o",*strp);
  821.                 else if(*strp == '"')
  822.                   fprintf(fpout,"\"\"",*strp);
  823.                 else if(*strp == '\\')
  824.                   fprintf(fpout,"\\\\");
  825.                 else
  826.                   fprintf(fpout,"%c",*strp);
  827.                 strp++;
  828.               }
  829.             fprintf(fpout,"\"\n");
  830.           }
  831.       }
  832.     fprintf(fpout,"END\n");
  833.     fseek(fp,fpos,0);
  834.     return(0);
  835.   }
  836. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  837.  
  838. int put_rcdata(fp,fpout,filep,tlen,rname,rid,flags)
  839.   FILE *fp,*fpout;
  840.   long filep,tlen;
  841.   char *rname;
  842.   USHORT rid;
  843.   USHORT flags;
  844.   {
  845.     long fpos;
  846.     char xname[16];
  847.     USHORT len;
  848.     long filelen;
  849.     USHORT i;
  850.     char first;
  851.     UCHAR c;         /*I don't like accessing arrays to much*/
  852.  
  853.     fpos = ftell(fp);
  854.  
  855.     fseek(fp,filep,0);
  856.     filelen = tlen;
  857.  
  858.     if(rname != NULL)
  859.       fprintf(fpout,"%s RCDATA ",rname);
  860.     else
  861.       fprintf(fpout,"%d RCDATA ",rid);
  862.     print_flags(fpout,flags,10);
  863.  
  864.     fprintf(fpout,"\nBEGIN\n");
  865.  
  866.     first = 1;
  867.     while(filelen)
  868.       {
  869.         len = fread(tmpbuf,1,(USHORT)MIN(filelen,TMPSIZE),fp);
  870.         for(i = 0; i < len; i++)
  871.           {
  872.             c = tmpbuf[i];
  873.  
  874.             if((i & 15) == 0)
  875.               {
  876.                 if(first)       /* are there better ways ??  sure ! */
  877.                   {
  878.                     fprintf(fpout,"\n  \"",c);
  879.                     first = 0;
  880.                   }
  881.                 else
  882.                   fprintf(fpout,"\",\n  \"",c);
  883.               }
  884.  
  885.             if(c >= ' ' && c <= '~')
  886.               fprintf(fpout,"%c",c);
  887.             else
  888.               {
  889.                 if(c == 0)              /* occurs quite often */
  890.                   fprintf(fpout,"\\0");
  891.                 else
  892.                   fprintf(fpout,"\\%03o",c);
  893.               }
  894.  
  895.             if (filelen-i <= 1)          fprintf(fpout,"\"");
  896.           }
  897.         filelen -= len;
  898.       }
  899.     fprintf(fpout,"\nEND\n");
  900.     fseek(fp,fpos,0);
  901.     return(0);
  902.   }
  903. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  904.  
  905. int put_accel(fp,fpout,filep,aname,aid,flags)
  906.   FILE *fp,*fpout;
  907.   long filep;
  908.   char *aname;
  909.   USHORT aid;
  910.   USHORT flags;
  911.   {
  912.     long fpos;
  913.     char xname[16];
  914.     char *vkname;
  915.     UCHAR keytype,keyval;
  916.     USHORT idval;
  917.  
  918.     fpos = ftell(fp);
  919.  
  920.     fseek(fp,filep,0);
  921.     if(aname != NULL)
  922.       fprintf(fpout,"%s ACCELERATORS ",aname);
  923.     else
  924.       fprintf(fpout,"%d ACCELERATORS ",aid);
  925.     print_flags(fpout,flags,9);
  926.  
  927.     fprintf(fpout,"\nBEGIN\n");
  928.     do
  929.       {
  930.         keytype = read_byte(fp);
  931.         keyval  = read_byte(fp);
  932.         read_byte(fp);                           /* skip dummy*/
  933.         idval = read_word(fp);
  934.         if((keytype & 0x01) == 0)                /*ascii */
  935.           {
  936.             if(keyval < 0x20)
  937.               fprintf(fpout,"  \"^%c\",%d",keyval+'@',idval);
  938.             else
  939.               fprintf(fpout,"  \"%c\",%d",keyval,idval);
  940.           }
  941.         else                             /*virtkey*/
  942.           {
  943.             if(keyval >= 'A' && keyval <= 'Z')
  944.               fprintf(fpout,"  \"%c\",%d,VIRTKEY",keyval,idval);
  945.             else if(keyval >= '0' && keyval <= '9')
  946.               fprintf(fpout,"  \"%c\",%d,VIRTKEY",keyval,idval);
  947.             else
  948.               {
  949.                 vkname = get_virttext(keyval);
  950.                 if(vkname != NULL)
  951.                   fprintf(fpout,"  VK_%s,%d,VIRTKEY",vkname,idval);
  952.                 else
  953.                   fprintf(fpout,"  %u,%d,VIRTKEY",keyval,idval);
  954.               }
  955.           }
  956.         if(keytype & 0x02)
  957.           fprintf(fpout,",NOINVERT");
  958.         if(keytype & 0x04)
  959.           fprintf(fpout,",SHIFT");
  960.         if(keytype & 0x08)
  961.           fprintf(fpout,",CONTROL");
  962.         if(keytype & 0x10)
  963.           fprintf(fpout,",ALT");
  964.         fprintf(fpout,"\n");
  965.       } while ( (keytype &0x80) == 0);
  966.     fprintf(fpout,"END\n");
  967.     fseek(fp,fpos,0);
  968.     return(0);
  969.   }
  970. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  971.  
  972. int put_menu(fp,fpout,filep,mname,mid,flags)
  973.   FILE *fp,*fpout;
  974.   long filep;
  975.   char *mname;
  976.   USHORT mid;
  977.   USHORT flags;
  978.   {
  979.     long fpos;
  980.     char xname[16];
  981.     int indent;
  982.     USHORT mflag,idval;
  983.     char menustr[256],*msp;    /*should be enough*/
  984.     char levelend[32],level;   /* have you seen an application
  985.                                   32 menu-levels deep ?? */
  986.  
  987.     for(level = 0; level < 32;level++)  levelend[level] = 0;
  988.     level = 0;
  989.  
  990.     fpos = ftell(fp);
  991.  
  992.     fseek(fp,filep,0);
  993.     read_dword(fp);                        /* unused*/
  994.  
  995.     if(mname != NULL)
  996.       fprintf(fpout,"%s MENU ",mname);
  997.     else
  998.       fprintf(fpout,"%d MENU ",mid);
  999.     print_flags(fpout,flags,4);
  1000.     fprintf(fpout,"\nBEGIN\n");
  1001.  
  1002.     indent = INDENTVAL;
  1003.     level++;
  1004.     levelend[0] = 1;
  1005.  
  1006.     while(level > 0)
  1007.       {
  1008.         mflag = read_word(fp);                    /*menu-flags*/
  1009.         if(!(mflag & MF_POPUP))
  1010.           idval = read_word(fp);                  /*id-value*/
  1011.  
  1012.         read_string(fp,menustr);
  1013.  
  1014.         if(mflag & MF_POPUP)
  1015.           {
  1016.             fprintf(fpout,"%sPOPUP \"%s\"",SPC(indent),menustr);
  1017.             if(mflag & MF_GRAYED)        fprintf(fpout,", GRAYED");
  1018.             if(mflag & MF_DISABLED)      fprintf(fpout,", INACTIVE");
  1019.             if(mflag & MF_CHECKED)       fprintf(fpout,", CHECKED");
  1020.             if(mflag & MF_MENUBARBREAK)  fprintf(fpout,", MENUBARBREAK");
  1021.             if(mflag & MF_MENUBREAK)     fprintf(fpout,", MENUBREAK");
  1022.             fprintf(fpout,"\n%sBEGIN\n",SPC(indent));
  1023.             indent += INDENTVAL;
  1024.             if(mflag & MF_END)
  1025.               {
  1026.                 levelend[level] = 1;
  1027.               }
  1028.             level++;
  1029.           }
  1030.         else
  1031.           {
  1032.             if(menustr[0] || (mflag & IS_MENUOPT))
  1033.               fprintf(fpout,"%sMENUITEM \"%s\", %d",SPC(indent),menustr,idval);
  1034.             else
  1035.               fprintf(fpout,"%sMENUITEM SEPARATOR",SPC(indent));
  1036.  
  1037.             if(mflag & MF_GRAYED)        fprintf(fpout,", GRAYED");
  1038.             if(mflag & MF_DISABLED)      fprintf(fpout,", INACTIVE");
  1039.             if(mflag & MF_CHECKED)       fprintf(fpout,", CHECKED");
  1040.             if(mflag & MF_MENUBARBREAK)  fprintf(fpout,", MENUBARBREAK");
  1041.             if(mflag & MF_MENUBREAK)     fprintf(fpout,", MENUBREAK");
  1042.             fprintf(fpout,"\n");
  1043.             if(mflag & MF_END)
  1044.               {
  1045.                 indent -= INDENTVAL;
  1046.                 level--;
  1047.                 fprintf(fpout,"%sEND\n",SPC(indent));
  1048.                 while(levelend[level] && level)
  1049.                   {
  1050.                     indent -= INDENTVAL;
  1051.                     level--;
  1052.                     fprintf(fpout,"%sEND\n",SPC(indent));
  1053.                   }
  1054.               }
  1055.           }
  1056.       }
  1057.     fseek(fp,fpos,0);
  1058.     return(0);
  1059.   }
  1060. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1061.  
  1062. int put_dialog(fp,fpout,filep,dname,did,flags)
  1063.   FILE *fp,*fpout;
  1064.   long filep;
  1065.   char *dname;
  1066.   USHORT did;
  1067.   USHORT flags;
  1068.   {
  1069.     long fpos;
  1070.     char xname[16];
  1071.     USHORT len;
  1072.     ULONG rstyle;
  1073.     UCHAR rclass;
  1074.     UCHAR nctrl;                    /* # of controls in box*/
  1075.     USHORT fontsize;
  1076.     char fontname[64];
  1077.     USHORT x,y,wid,hei,idval;
  1078.     UCHAR text[256],*txtp;                 /* should be enough*/
  1079.     char classname[256],*classp;
  1080.     int i;
  1081.     int numref;
  1082.     long filelen;
  1083.  
  1084.     fpos = ftell(fp);
  1085.  
  1086.     fseek(fp,filep,0);    /* and back*/
  1087.  
  1088.     rstyle = read_dword(fp);        /* dlgbox-style*/
  1089.     nctrl = read_byte(fp);          /* # controls*/
  1090.     x     = read_word(fp);
  1091.     y     = read_word(fp);
  1092.     wid   = read_word(fp);
  1093.     hei   = read_word(fp);
  1094.  
  1095.     if(dname != NULL)
  1096.       fprintf(fpout,"%s DIALOG ",dname);
  1097.     else
  1098.       fprintf(fpout,"%d DIALOG ",did);
  1099.     print_flags(fpout,flags,5);
  1100.  
  1101.     fprintf(fpout," %d, %d, %d, %d\n",x,y,wid,hei);
  1102.     fprintf(fpout,"STYLE ");
  1103.     print_styles(fpout,rstyle,0);
  1104.     fprintf(fpout,"\n");
  1105.  
  1106.     if(read_textorid(fp,text,&numref) == GOT_ID)   /* MENU name*/
  1107.       fprintf(fpout,"MENU %d\n",numref);
  1108.     else if(text[0])
  1109.       fprintf(fpout,"MENU \"%s\"\n",text);
  1110.  
  1111.     if(read_textorid(fp,text,&numref) == GOT_ID)   /* CLASS name*/
  1112.       fprintf(fpout,"CLASS %d\n",numref);
  1113.     else if(text[0])
  1114.       fprintf(fpout,"CLASS \"%s\"\n",text);
  1115.  
  1116.     if(read_textorid(fp,text,&numref) == GOT_ID)   /* CAPTION */
  1117.       fprintf(fpout,"CAPTION %d\n",numref);
  1118.     else if(text[0])
  1119.       fprintf(fpout,"CAPTION \"%s\"\n",text);
  1120.  
  1121.     if(rstyle & DS_SETFONT)
  1122.       {
  1123.         fontsize = read_word(fp);
  1124.         read_string(fp,fontname);
  1125.         fprintf(fpout,"FONT %u,\"%s\"\n",fontsize,fontname);
  1126.       }
  1127.  
  1128.  
  1129.     fprintf(fpout,"\nBEGIN\n");
  1130.  
  1131.     for(i = 0; i < nctrl;i++)
  1132.       {
  1133.         x     = read_word(fp);
  1134.         y     = read_word(fp);
  1135.         wid   = read_word(fp);
  1136.         hei   = read_word(fp);
  1137.         idval = read_word(fp);
  1138.         rstyle = read_dword(fp);         /* ctrl-style*/
  1139.         rclass = read_byte(fp);          /* class (std or by name) */
  1140.         if(rclass < 0x80 || rclass > 0x85)   /* non standard class*/
  1141.           {
  1142.             classname[0] = rclass;
  1143.             if(rclass)
  1144.               read_string(fp,classname+1);
  1145.           }
  1146.         else
  1147.           {
  1148.             strcpy(classname,stdclassname[rclass & 0x0f]);
  1149.           }
  1150.  
  1151.         if(read_textorid(fp,text,&numref) == GOT_ID)
  1152.             fprintf(fpout,"  CONTROL %d, %d,\"%s\",",
  1153.                            numref,idval,classname,rstyle,x,y,wid,hei);
  1154.         else
  1155.             fprintf(fpout,"  CONTROL \"%s\", %d,\"%s\",",
  1156.                           text,idval,classname,rstyle,x,y,wid,hei);
  1157.  
  1158.         read_byte(fp);                        /*there's another 0*/
  1159.         if(rclass < 0x80 || rclass > 0x85)   /* non standard class*/
  1160.           {
  1161.             fprintf(fpout,"0x%08lX",rstyle);
  1162.           }
  1163.         else
  1164.           {
  1165.             print_styles(fpout,rstyle,rclass);
  1166.           }
  1167.         fprintf(fpout,",%d, %d, %d, %d\n",
  1168.                        x,y,wid,hei);
  1169.       }
  1170.     fprintf(fpout,"END\n");
  1171.     fseek(fp,fpos,0);
  1172.     return(0);
  1173.   }
  1174. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1175.  
  1176. int put_nametab(fp,fpout,filep)
  1177.   FILE *fp,*fpout;
  1178.   long filep;
  1179.   {
  1180.     long fpos;
  1181.     char xname[16];
  1182.     char rcname[256];
  1183.     USHORT len,rctype,rcnum,i;
  1184.     long filelen;
  1185.  
  1186.     fpos = ftell(fp);
  1187.  
  1188.     fseek(fp,filep,0);    /* and back*/
  1189.  
  1190.     while(len = read_word(fp))
  1191.       {
  1192.         rctype = read_word(fp);
  1193.         rctype &= 0x000f;
  1194.         rctype %= 11;             /* refs to icons are refs to iconheaders
  1195.                                      same for bitmaps, think about that */
  1196.         rcnum = read_word(fp);
  1197.         rcnum &= 0x7fff;
  1198.         read_byte(fp);            /* skip 1 byte */
  1199.         fread(rcname,1,len-7,fp);   /* may use read_string, but this is safe*/
  1200.         fprintf(fpout,"%s %s @%d\n",rcname,resname[rctype],rcnum);
  1201.       }
  1202.     fseek(fp,fpos,0);
  1203.     return(0);
  1204.   }
  1205. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1206.  
  1207. int print_styles(fpout,rstyle,rclass)
  1208.   FILE *fpout;
  1209.   ULONG rstyle;
  1210.   UCHAR rclass;
  1211.   {
  1212.                              /* common window styles*/
  1213.     fprintf(fpout,"0");      /* sorry!*/
  1214.     if(rstyle & WS_VISIBLE)
  1215.       fprintf(fpout,"|WS_VISIBLE");
  1216.     if(rstyle & WS_POPUP)
  1217.       fprintf(fpout,"|WS_POPUP");
  1218.     if(rstyle & WS_CHILD)
  1219.       fprintf(fpout,"|WS_CHILD");
  1220.     if(rstyle & WS_MINIMIZE)
  1221.       fprintf(fpout,"|WS_MINIMIZE");
  1222.     if(rstyle & WS_DISABLED)
  1223.       fprintf(fpout,"|WS_DISABLED");
  1224.     if(rstyle & WS_DISABLED)
  1225.       fprintf(fpout,"|WS_DISABLED");
  1226.     if(rstyle & WS_CLIPSIBLINGS)
  1227.       fprintf(fpout,"|WS_CLIPSIBLINGS");
  1228.     if(rstyle & WS_CLIPCHILDREN)
  1229.       fprintf(fpout,"|WS_CLIPCHILDREN");
  1230.     if(rstyle & WS_MAXIMIZE)
  1231.       fprintf(fpout,"|WS_MAXIMIZE");
  1232.     if((rstyle & WS_CAPTION) == WS_CAPTION)
  1233.       fprintf(fpout,"|WS_CAPTION");
  1234.     else
  1235.       {
  1236.         if(rstyle & WS_BORDER)
  1237.           fprintf(fpout,"|WS_BORDER");
  1238.         if(rstyle & WS_DLGFRAME)
  1239.           fprintf(fpout,"|WS_DLGFRAME");
  1240.       }
  1241.     if(rstyle & WS_VSCROLL)
  1242.       fprintf(fpout,"|WS_VSCROLL");
  1243.     if(rstyle & WS_HSCROLL)
  1244.       fprintf(fpout,"|WS_HSCROLL");
  1245.     if(rstyle & WS_SYSMENU)
  1246.       fprintf(fpout,"|WS_SYSMENU");
  1247.     if(rstyle & WS_THICKFRAME)
  1248.       fprintf(fpout,"|WS_THICKFRAME");
  1249.     if(rstyle & WS_GROUP)
  1250.       fprintf(fpout,"|WS_GROUP");
  1251.     if(rstyle & WS_TABSTOP)
  1252.       fprintf(fpout,"|WS_TABSTOP");
  1253.     if(rstyle & WS_MINIMIZEBOX)
  1254.       fprintf(fpout,"|WS_MINIMIZEBOX");
  1255.     if(rstyle & WS_MAXIMIZEBOX)
  1256.       fprintf(fpout,"|WS_MAXIMIZEBOX");
  1257.     if(rclass == 0)                     /* is dialog-box style*/
  1258.       {
  1259.         if(rstyle & DS_ABSALIGN)
  1260.           fprintf(fpout,"|DS_ABSALIGN");
  1261.         if(rstyle & DS_SYSMODAL)
  1262.           fprintf(fpout,"|DS_SYSMODAL");
  1263.         if(rstyle & DS_LOCALEDIT)
  1264.           fprintf(fpout,"|DS_LOCALEDIT");
  1265.         if(rstyle & DS_SETFONT)
  1266.           fprintf(fpout,"|DS_SETFONT");
  1267.         if(rstyle & DS_MODALFRAME)
  1268.           fprintf(fpout,"|DS_MODALFRAME");
  1269.         if(rstyle & DS_NOIDLEMSG)
  1270.           fprintf(fpout,"|DS_NOIDLEMSG");
  1271.       }
  1272.     else if(rclass == 0x80)                     /* button styles*/
  1273.       {
  1274.         fprintf(fpout,"|%s",button_text[rstyle & 0x0fL]);
  1275.         if(rstyle & BS_LEFTTEXT)
  1276.           fprintf(fpout,"|BS_LEFTTEXT");
  1277.       }
  1278.     else if(rclass == 0x81)                     /* edit styles*/
  1279.       {
  1280.         fprintf(fpout,"|%s",edit_text[rstyle & 0x03L]);
  1281.         if(rstyle & ES_MULTILINE)
  1282.           fprintf(fpout,"|ES_MULTILINE");
  1283.         if(rstyle & ES_UPPERCASE)
  1284.           fprintf(fpout,"|ES_UPPERCASE");
  1285.         if(rstyle & ES_LOWERCASE)
  1286.           fprintf(fpout,"|ES_LOWERCASE");
  1287.         if(rstyle & ES_PASSWORD)
  1288.           fprintf(fpout,"|ES_PASSWORD");
  1289.         if(rstyle & ES_AUTOVSCROLL)
  1290.           fprintf(fpout,"|ES_AUTOVSCROLL");
  1291.         if(rstyle & ES_AUTOHSCROLL)
  1292.           fprintf(fpout,"|ES_AUTOHSCROLL");
  1293.         if(rstyle & ES_NOHIDESEL)
  1294.           fprintf(fpout,"|ES_NOHIDESEL");
  1295.         if(rstyle & ES_OEMCONVERT)
  1296.           fprintf(fpout,"|ES_OEMCONVERT");
  1297.       }
  1298.     else if(rclass == 0x82)                     /* static styles*/
  1299.       {
  1300.         fprintf(fpout,"|%s",static_text[rstyle & 0x0fL]);
  1301.         if(rstyle & SS_NOPREFIX)
  1302.           fprintf(fpout,"|SS_NOPREFIX");
  1303.       }
  1304.     else if(rclass == 0x83)                     /* listbox styles*/
  1305.       {
  1306.         if(rstyle & LBS_NOTIFY)
  1307.           fprintf(fpout,"|LBS_NOTIFY");
  1308.         if(rstyle & LBS_SORT)
  1309.           fprintf(fpout,"|LBS_SORT");
  1310.         if(rstyle & LBS_NOREDRAW)
  1311.           fprintf(fpout,"|LBS_NOREDRAW");
  1312.         if(rstyle & LBS_MULTIPLESEL)
  1313.           fprintf(fpout,"|LBS_MULTIPLESEL");
  1314.         if(rstyle & LBS_OWNERDRAWFIXED)
  1315.           fprintf(fpout,"|LBS_OWNERDRAWFIXED");
  1316.         if(rstyle & LBS_OWNERDRAWVARIABLE)
  1317.           fprintf(fpout,"|LBS_OWNERDRAWVARIABLE");
  1318.         if(rstyle & LBS_HASSTRINGS)
  1319.           fprintf(fpout,"|LBS_HASSTRINGS");
  1320.         if(rstyle & LBS_USETABSTOPS)
  1321.           fprintf(fpout,"|LBS_USETABSTOPS");
  1322.         if(rstyle & LBS_NOINTEGRALHEIGHT)
  1323.           fprintf(fpout,"|LBS_NOINTEGRALHEIGHT");
  1324.         if(rstyle & LBS_MULTICOLUMN)
  1325.           fprintf(fpout,"|LBS_MULTICOLUMN");
  1326.         if(rstyle & LBS_WANTKEYBOARDINPUT)
  1327.           fprintf(fpout,"|LBS_WANTKEYBOARDINPUT");
  1328.         if(rstyle & LBS_EXTENDEDSEL)
  1329.           fprintf(fpout,"|LBS_EXTENDEDSEL");
  1330.       }
  1331.     else if(rclass == 0x84)                     /* scrollbar styles*/
  1332.       {
  1333.  
  1334.         if(rstyle & SBS_VERT)
  1335.           {
  1336.             fprintf(fpout,"|SBS_VERT");
  1337.             if(rstyle & SBS_LEFTALIGN)
  1338.               fprintf(fpout,"|SBS_LEFTALIGN");
  1339.             if(rstyle & SBS_RIGHTALIGN)
  1340.               fprintf(fpout,"|SBS_RIGHTALIGN");
  1341.           }
  1342.         else
  1343.           {
  1344.             fprintf(fpout,"|SBS_HORZ");
  1345.             if(rstyle & SBS_TOPALIGN)
  1346.               fprintf(fpout,"|SBS_TOPALIGN");
  1347.             if(rstyle & SBS_BOTTOMALIGN)
  1348.               fprintf(fpout,"|SBS_BOTTOMALIGN");
  1349.           }
  1350.  
  1351.         if(rstyle & SBS_SIZEBOX)
  1352.           {
  1353.             fprintf(fpout,"|SBS_SIZEBOX");
  1354.             if(rstyle & SBS_SIZEBOXTOPLEFTALIGN)
  1355.               fprintf(fpout,"|SBS_SIZEBOXTOPLEFTALIGN");
  1356.             if(rstyle & SBS_SIZEBOXBOTTOMRIGHTALIGN)
  1357.               fprintf(fpout,"|SBS_SIZEBOXBOTTOMRIGHTALIGN");
  1358.           }
  1359.       }
  1360.     else if(rclass == 0x85)                     /* combobox styles*/
  1361.       {
  1362.         fprintf(fpout,"|%s",combo_text[rstyle & 0x03L]);
  1363.         if(rstyle & CBS_OWNERDRAWFIXED)
  1364.           fprintf(fpout,"|CBS_OWNERDRAWFIXED");
  1365.         if(rstyle & CBS_OWNERDRAWVARIABLE)
  1366.           fprintf(fpout,"|CBS_OWNERDRAWVARIABLE");
  1367.         if(rstyle & CBS_AUTOHSCROLL)
  1368.           fprintf(fpout,"|CBS_AUTOHSCROLL");
  1369.         if(rstyle & CBS_OEMCONVERT)
  1370.           fprintf(fpout,"|CBS_OEMCONVERT");
  1371.         if(rstyle & CBS_SORT)
  1372.           fprintf(fpout,"|CBS_SORT");
  1373.         if(rstyle & CBS_HASSTRINGS)
  1374.           fprintf(fpout,"|CBS_HASSTRINGS");
  1375.         if(rstyle & CBS_NOINTEGRALHEIGHT)
  1376.           fprintf(fpout,"|CBS_NOINTEGRALHEIGHT");
  1377.       }
  1378.     return(0);
  1379.   }
  1380. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1381.  
  1382. char *get_virttext(val)
  1383.   UCHAR val;
  1384.   {
  1385.     TEXTTAB *tp;
  1386.     tp = virt_text;
  1387.     while(tp->val)
  1388.       {
  1389.         if(tp->val == val)    return(tp->text);
  1390.         tp++;
  1391.       }
  1392.     return(NULL);
  1393.   }
  1394.  
  1395. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1396. /* helper functions              */
  1397. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1398.  
  1399. int read_string(fp,str)          /* read string with terminating 0*/
  1400.   FILE *fp;
  1401.   char *str;
  1402.   {
  1403.     int cnt;
  1404.  
  1405.     cnt = 0;
  1406.                              /*get string with terminating 0*/
  1407.     do { fread(str,1,1,fp); cnt++;} while(*str++);
  1408.     return(cnt-1);           /* return strlen */
  1409.   }
  1410. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1411.  
  1412. int read_nstring(fp,str,n)      /* read string of length n,
  1413.                                    add terminating 0*/
  1414.   FILE *fp;
  1415.   char *str;
  1416.   USHORT n;
  1417.   {
  1418.     fread(str,n,1,fp);       /*size n, because we want it with
  1419.                                only one read (say 'hi' to *nix & *icrosoft)*/
  1420.     str[n] = '\0';
  1421.     return(n);               /* return strlen */
  1422.   }
  1423. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1424.  
  1425. USHORT read_word(fp)
  1426.   FILE *fp;
  1427.   {
  1428.     USHORT tmp;
  1429.     fread(&tmp,2,1,fp);
  1430.     return(tmp);
  1431.   }
  1432. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1433.  
  1434. ULONG read_dword(fp)
  1435.   FILE *fp;
  1436.   {
  1437.     ULONG tmp;
  1438.     fread(&tmp,4,1,fp);
  1439.     return(tmp);
  1440.   }
  1441. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1442.  
  1443. UCHAR read_byte(fp)
  1444.   FILE *fp;
  1445.   {
  1446.     UCHAR tmp;
  1447.     fread(&tmp,1,1,fp);
  1448.     return(tmp);
  1449.   }
  1450. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1451.  
  1452. int copy_block(fpto,fp,size)
  1453.   FILE *fpto,*fp;
  1454.   ULONG size;
  1455.   {
  1456.     USHORT len;
  1457.  
  1458.     while(size)
  1459.       {
  1460.         len = fread(tmpbuf,1,(USHORT)MIN(size,TMPSIZE),fp);
  1461.         fwrite(tmpbuf,1,len,fpto);
  1462.         size -= (ULONG)len;
  1463.       }
  1464.     return(0);
  1465.   }
  1466. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1467.  
  1468. int read_textorid(fp,text,idp)
  1469.   FILE *fp;
  1470.   char *text;
  1471.   int *idp;
  1472.   {
  1473.     UCHAR chkc;
  1474.  
  1475.     chkc = read_byte(fp);
  1476.     if(chkc == 0xff)  /* undocumented numerical reference*/
  1477.       {
  1478.         *idp = read_word(fp);
  1479.         return(GOT_ID);
  1480.       }
  1481.     text[0] = chkc;
  1482.     if(chkc)      read_string(fp,text+1);    /*there is text*/
  1483.     return(GOT_TEXT);
  1484.   }
  1485. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1486.  
  1487. char *lookup_name(rce,type)
  1488.   RCENTRY *rce;
  1489.   USHORT type;
  1490.   {
  1491.     int i;
  1492.  
  1493.     type &= 0x000f;
  1494.     type %= 11;
  1495.     for(i = 0; i < ntentry; i++)
  1496.       {
  1497.         if(((rce->id & 0x7fff) == (nametab[i].num & 0x7fff)) &&
  1498.            (type == nametab[i].type))
  1499.           return(nametab[i].name);
  1500.       }
  1501.     return(NULL);
  1502.   }
  1503. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1504.  
  1505. int print_flags(fp,flg,type)
  1506.   FILE *fp;
  1507.   USHORT flg;
  1508.   USHORT type;
  1509.   {
  1510.     if(type != 2)   /* BITMAP*/
  1511.       {
  1512.         if( (flg & FLAG_MASK) == (MEMF_DISC|MEMF_MOVE))
  1513.           return(0);   /* is default*/
  1514.       }
  1515.     else
  1516.       {
  1517.         if( (flg & FLAG_MASK) == MEMF_MOVE)
  1518.           return(0);
  1519.       }
  1520.  
  1521.     if(flg & MEMF_PREL)           /*PRELOAD*/
  1522.       fprintf(fp,"PRELOAD ");
  1523.     else
  1524.       fprintf(fp,"LOADONCALL ");
  1525.  
  1526.     if(flg & MEMF_DISC)           /*DISCARDABLE*/
  1527.       fprintf(fp,"DISCARDABLE ");
  1528.  
  1529.     if(flg & MEMF_MOVE)           /*MOVEABLE*/
  1530.       fprintf(fp,"MOVEABLE ");
  1531.     else
  1532.       fprintf(fp,"FIXED ");
  1533.  
  1534.  
  1535.     return(0);
  1536.   }
  1537. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1538.